package com.ostrich.cloud.ostrichGoodsService.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ostrich.cloud.common.result.PageResult;
import com.ostrich.cloud.ostrichGoodsSercice.model.Dto.GoodsDto;
import com.ostrich.cloud.ostrichGoodsService.common.exception.OstrichGoodsException;
import com.ostrich.cloud.ostrichGoodsService.common.exception.OstrichGoodsExceptionCode;
import com.ostrich.cloud.ostrichGoodsService.common.status.OstrichGoodsStatus;
import com.ostrich.cloud.ostrichGoodsService.infra.model.Goods;
import com.ostrich.cloud.ostrichGoodsService.infra.mapper.GoodsMapper;
import com.ostrich.cloud.ostrichGoodsService.service.GoodsService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ostrich.cloud.ostrichGoodsService.service.param.AddGoodsParam;
import com.ostrich.cloud.ostrichGoodsService.service.param.SelectGoodsParam;
import com.ostrich.cloud.ostrichGoodsService.service.param.UpdateGoodsParam;
//import io.seata.spring.annotation.GlobalTransactional;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RScoredSortedSet;
import org.redisson.api.RedissonClient;
import org.redisson.client.protocol.ScoredEntry;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * <p>
 * 物品表 服务实现类
 * </p>
 *
 * @author Lucas
 * @since 2022-10-26
 */
@Service
@Slf4j
public class GoodsServiceImpl extends ServiceImpl<GoodsMapper, Goods> implements GoodsService {

    @Resource
    private GoodsMapper goodsMapper;

    @Resource
    private RedissonClient redissonClient;

    @Override
    public GoodsDto getGoodsDto(Integer goodsId) {


        Goods goods = goodsMapper.selectById(goodsId);
        if(goods==null){
            throw new OstrichGoodsException(OstrichGoodsExceptionCode.GOODS_GET_EXCEPTION);
        }
        GoodsDto goodsDto = BeanUtil.copyProperties(goods, GoodsDto.class);
        return goodsDto;
    }

    @Override

    @Transactional
    public Boolean addGoods(AddGoodsParam addGoodsParam) {
        Goods goods = BeanUtil.copyProperties(addGoodsParam, Goods.class);
        goods.setGoodsStatus(OstrichGoodsStatus.DOWN);
        goods.setSales(0);
        log.info("开始创建商品{}",goods);
        int insert = goodsMapper.insert(goods);
        log.info("创建完成{}",goods);
        if(insert<1){
            throw new OstrichGoodsException(OstrichGoodsExceptionCode.TYPE_DEL_DB_EXCEPTION);
        }

        return true;
    }

    @Override
    public PageResult<GoodsDto> selectGoodsDto(SelectGoodsParam param) {
        log.info("开始查询商品{}",param);
        QueryWrapper<Goods> wrapper = new QueryWrapper<>();
        wrapper.eq(param.getTypeId()!=null,"type_id",param.getTypeId())
                .eq(param.getBusinessmanId()!=null,"businessman_id",param.getBusinessmanId())
                .in(param.getGoodsStatus()==null,"goods_status",OstrichGoodsStatus.ON,OstrichGoodsStatus.SLOD_OUT)
                .eq(param.getGoodsStatus()!=null,"goods_status",param.getGoodsStatus())
                .like(StrUtil.isNotBlank(param.getGoodsName()),"goods_name",param.getGoodsName());
        PageResult<GoodsDto> goodsDtoPageResult=null;
        log.info("开始查询商品{}",param);
        IPage<Goods> goodsIPage = goodsMapper.selectPage(new Page<Goods>(param.getCurrent(), param.getSize()), wrapper);
        return getGoodsDtoPageResult(goodsDtoPageResult, goodsIPage);
    }

    @Override
    public PageResult<GoodsDto> selectAllGoodsDto(Integer current, Integer size) {
        QueryWrapper<Goods> wrapper = new QueryWrapper<>();
        PageResult<GoodsDto> goodsDtoPageResult=null;
        log.info("开始查询商品");
        IPage<Goods> goodsIPage = goodsMapper.selectPage(new Page<Goods>(current, size), wrapper);
        return getGoodsDtoPageResult(goodsDtoPageResult, goodsIPage);

    }

    @Override
    @GlobalTransactional
    public boolean updateGoods(UpdateGoodsParam updateGoodsParam) {
        if(updateGoodsParam.getGoodsId()==null){
            throw new OstrichGoodsException(OstrichGoodsExceptionCode.GOODS_PARAM_EXCEPTION);
        }

        Goods goods1 = goodsMapper.selectById(updateGoodsParam.getGoodsId());
        if(goods1==null){
            throw new OstrichGoodsException(OstrichGoodsExceptionCode.GOODS_GET_EXCEPTION);
        }

        Goods goods = BeanUtil.copyProperties(updateGoodsParam, Goods.class);

        int i = goodsMapper.updateById(goods);
        if(i<1){
            throw new OstrichGoodsException(OstrichGoodsExceptionCode.TYPE_DEL_DB_EXCEPTION);
        }
        return true;
    }

    @Override
    @Transactional
    public boolean delGoods(Integer goodsId) {

        int i = goodsMapper.deleteById(goodsId);
        if(i<1){
            throw new OstrichGoodsException(OstrichGoodsExceptionCode.TYPE_DEL_DB_EXCEPTION);
        }

        return true;
    }

    @Override
    public List<GoodsDto> getHotGoods() {

        RScoredSortedSet<Goods> products = redissonClient.getScoredSortedSet("products");
        Collection<ScoredEntry<Goods>> scoredEntries = products.entryRangeReversed(0, 5);
        List<Goods> goods2 = new ArrayList<>();
        products.clear();
        for (ScoredEntry<Goods> s:scoredEntries){
            Goods value = s.getValue();
            goods2.add(value);
        }
        List<GoodsDto> goodsDtos = BeanUtil.copyToList(goods2, GoodsDto.class);
        return goodsDtos;
    }

    private PageResult<GoodsDto> getGoodsDtoPageResult(PageResult<GoodsDto> goodsDtoPageResult, IPage<Goods> goodsIPage) {
        if (goodsIPage != null && CollectionUtil.isNotEmpty(goodsIPage.getRecords())) {
            goodsDtoPageResult = new PageResult<>();
            List<GoodsDto> goodsDtos = BeanUtil.copyToList(goodsIPage.getRecords(), GoodsDto.class);
            goodsDtoPageResult.setElements(goodsDtos);
            goodsDtoPageResult.setTotal(goodsIPage.getTotal());
            goodsDtoPageResult.setTotalPage(goodsIPage.getPages());
            goodsDtoPageResult.setPageSize(goodsIPage.getSize());
            goodsDtoPageResult.setPage(goodsIPage.getCurrent());
        }
        log.info("查询完成{}", goodsDtoPageResult);
        return goodsDtoPageResult;
    }
}
